<?php
class PostsController extends AppController {

	var $name = 'Posts';
    var $components = array('Upload','Json');
    var $helpers = array('Javascript');

    function beforeFilter(){
        parent::beforeFilter();
        $this->Auth->allow('index','view','search','find');
    }

    /**
     * Index page of Freelogo.web.id CMS
     * usage in : /posts/index.ctp
     */
	function index() {
        /* Get referer */
        $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
        if(!empty($referer)){
            $this->_getReferalHost($referer);
        }
            
        /* Get 5 post by Rates, post by View, post by Comments */
        $postRates = $this->Post->postOrderByRate();
        $postPopulars = $this->Post->postOrderByView();
        $postComments = $this->Post->postOrderByComment();

        /* Get 5 post by date and croping description to be one paragraph only */
        $getPostNews = $this->Post->postOrderByDate();
        $getComments = $this->Post->Comment->getNewComments();

        /* Filtering Post by cropping description to be one paragraph only */
        $postNews = $this->_filterDescription($getPostNews);

        /* Croping comment description to be one paragraph only */
        $comments = $this->_filterComment($getComments);

        $this->set(compact('postNews','postRates','postPopulars','postComments','comments'));
	}

    /**
     * Viewing page of logo
     * usage in : /posts/view.ctp
     */
	function view($slug = null) {
		if (!$slug) {
			$this->Session->setFlash(__('Invalid Post.', true));
			$this->redirect(array('action'=>'index'));
		}else{
            App::import('Sanitize');
            $cleanSlug = Sanitize::escape($slug);
            $post = $this->Post->getPostBySlug($slug);
            if(!empty($post)){
                $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
                if(!empty($referer)){
                    $this->_getReferalHost($referer);
                }
                
                $nextPost = $this->Post->getNextPost($post['Post']['post_id']);
                $prevPost = $this->Post->getPrevPost($post['Post']['post_id']);                
                
                /* Updating views +1*/
                $this->Post->updateAll(array('Post.view'=>"Post.view+1"),array('Post.post_id'=>$post['Post']['post_id']));

                 /* LInking Post and Catalog*/
                $this->Post->bindModel(
                    array('hasOne' => array('Catalog'=>array('className'=>'Catalog','foreignKey'=>'post_id'))
                    )
                );
                $arrayTag = Set::extract($post['Tag'], '{n}.name');
                $tag = implode($arrayTag,' ');
               
                $relatedPost = $this->Post->Catalog->getRelated($post['Category']['category_id'],$tag,$post['Post']['post_id']);
                $listCategory = array_keys($relatedPost['0']);
                $listTag = array_keys($relatedPost['1']);
                $combine = am($listCategory,$listTag); /* Merge array by Category and array by Tag */
                $getAll = array_count_values($combine); /* Counting same values */
                arsort($getAll); /* Sorting from highest value */
                $post_id = array_keys($getAll);

                $relatedPosts = $this->Post->getRelatedPost($post_id);
                
                $this->set(compact('post','nextPost','prevPost','relatedPosts'));
                $this->paginate = $this->Post->Comment->showAllComments();
                $this->set('comments', $this->paginate('Comment',array('AND'=>array('Comment.status'=>'1','Comment.post_id'=>$post['Post']['post_id']))));
            }else{
			$this->Session->setFlash(__('Invalid Post.', true));
			$this->redirect(array('action'=>'index'));
            }
        }
	}

	function add() {
        $this->layout = 'admin';
		if (!empty($this->data)) {
			$this->Post->create();
			if ($this->Post->save($this->data)) {
				$this->Session->setFlash(__('The Post has been saved', true));
				$this->redirect(array('action'=>'index'));
			} else {
				$this->Session->setFlash(__('The Post could not be saved. Please, try again.', true));
			}
		}
        $categories = $this->Post->Category->find('list');
        $this->set('categories',$categories);
	}

	function edit($id = null) {
		if (!$id && empty($this->data)) {
			$this->Session->setFlash(__('Invalid Post', true));
			$this->redirect(array('action'=>'index'));
		}
		if (!empty($this->data)) {
			if ($this->Post->save($this->data)) {
				$this->Session->setFlash(__('The Post has been saved', true));
				$this->redirect(array('action'=>'index'));
			} else {
				$this->Session->setFlash(__('The Post could not be saved. Please, try again.', true));
			}
		}
		if (empty($this->data)) {
			$this->data = $this->Post->read(null, $id);
		}
	}

	function delete($id = null) {
		if (!$id) {
			$this->Session->setFlash(__('Invalid id for Post', true));
			$this->redirect(array('action'=>'index'));
		}
		if ($this->Post->del($id)) {
			$this->Session->setFlash(__('Post deleted', true));
			$this->redirect(array('action'=>'index'));
		}
	}

    /**
     * Home administator page
     * first login page
     */
    function home(){
        $this->layout = 'admin';
    }


     /**
      * Saving and published Post
      * usage in : /posts/add.ctp
      */
    function savePost(){
        $this->layout = 'ajax';
        Configure::write('debug',1);
        App::import('Sanitize');

        /* Defining tags array variables from ajax input */
        $title = Sanitize::escape(strtolower($this->params['form']['title']));
        $input_description = Sanitize::html($this->params['form']['description']);
        $category = Sanitize::html($this->params['form']['category']);
        $post_id = Sanitize::paranoid($this->params['form']['id']);
        $meta = Sanitize::escape(strtolower($this->params['form']['meta']));
        $keyword = Sanitize::escape(strtolower($this->params['form']['keyword']));

        if(empty($title)){$this->Json->error('0');}
        if(empty($input_description)){$this->Json->error('1');}
        if(empty($post_id)){$this->Json->error('2');}

        /* Processing description */
       $paragraph = explode("\n\n",$input_description);
        foreach($paragraph as $value=>&$key){
            $filterKey = '<p>'.$key.'</p>';
            $key = nl2br($filterKey);
        }
        $getDescription = implode(" ",$paragraph);
        $description = str_replace('\n','<br />',$getDescription);
            
         /* Creating and Modifiying Post title's and slug's' */
        $postTitle  = substr($title,0,200);												// maximum title is 200 characters
        $slugList	 = $this->Post->checkTitle($postTitle);                  	// checking title is exist or not
        $slug 		  = Inflector::slug(strtolower($slugList));
        $postSlug  = $this->Post->checkSlug($slug);                           // slug of album title created
            
        $this->data['Post']['title'] = $postTitle;
        $this->data['Post']['slug'] = $postSlug;
        $this->data['Post']['description'] = $description;
        $this->data['Post']['category_id'] = $category;
        $this->data['Post']['meta'] = $meta;
        $this->data['Post']['keyword'] = $keyword;
        $this->data['Post']['status'] = '1';

        $this->Post->id = $post_id;
     
        if($this->Post->save($this->data)){

            /* Building information for updating Catalog information */
            $getPost = $this->Post->getPostForCatalog($post_id);

            $arrayTag = Set::extract($getPost['Tag'], '{n}.name');
            $tags = implode($arrayTag,' ');
            
             /* LInking Post and Catalog*/
            $this->Post->bindModel(
                array('hasOne' => array('Catalog'=>array('className'=>'Catalog','foreignKey'=>'post_id'))
                )
            );
            $catalogId = $this->Post->Catalog->updateData($post_id,$getPost['Post']['title'],$getPost['Post']['category_id'],$getPost['Category']['name'],$tags,$description);            

            $this->Json->show(array('result'=>$postSlug));     // Show result and tags
        }
    }

     /**
      * Saving post as Draft
      * usage in : /posts/add.ctp
      */
    function saveDraft(){
        $this->layout = 'ajax';
        Configure::write('debug',0);
        App::import('Sanitize');

        /* Defining tags array variables from ajax input */
        $title = Sanitize::escape(strtolower($this->params['form']['title']));
        $input_description = Sanitize::html($this->params['form']['description']);
        $category = Sanitize::html($this->params['form']['category']);
        $post_id = Sanitize::paranoid($this->params['form']['id']);
        $meta = Sanitize::escape(strtolower($this->params['form']['meta']));
        $keyword = Sanitize::escape(strtolower($this->params['form']['keyword']));

        if(empty($title)){$this->Json->error('0');}
        if(empty($input_description)){$this->Json->error('1');}
        if(empty($post_id)){$this->Json->error('2');}

        /* Processing description */
        $paragraph = explode("\n\n",$input_description);
        foreach($paragraph as $value=>&$key){
            $filterKey = '<p>'.$key.'</p>';
            $key = nl2br($filterKey);
        }
        $getDescription = implode(" ",$paragraph);
        $description = str_replace('\n','<br />',$getDescription);

         /* Creating and Modifiying Post title's and slug's' */
        $postTitle  = substr($title,0,200);												// maximum title is 200 characters
        $slugList	 = $this->Post->checkTitle($postTitle);                  	// checking title is exist or not
        $slug 		  = Inflector::slug(strtolower($slugList));
        $postSlug  = $this->Post->checkSlug($slug);                           // slug of album title created

        $this->data['Post']['title'] = $postTitle;
        $this->data['Post']['slug'] = $postSlug;
        $this->data['Post']['description'] = $description;
        $this->data['Post']['category_id'] = $category;
        $this->data['Post']['meta'] = $meta;
        $this->data['Post']['keyword'] = $keyword;
        $this->data['Post']['status'] = '0';

        $this->Post->id = $post_id;

        if($this->Post->save($this->data)){
            /* Building information for updating Catalog information */
            $getPost = $this->Post->getPostForCatalog($post_id);

            $arrayTag = Set::extract($getPost['Tag'], '{n}.name');
            $tags = implode($arrayTag,' ');

             /* LInking Post and Catalog*/
            $this->Post->bindModel(
                array('hasOne' => array('Catalog'=>array('className'=>'Catalog','foreignKey'=>'post_id'))
                )
            );
            $catalogId = $this->Post->Catalog->updateData($post_id,$getPost['Post']['title'],$getPost['Post']['category_id'],$getPost['Category']['name'],$tags,$description);

            $this->Json->show(array('result'=>$postSlug));     // Show result and tags
        }
    }

    /**
      * Creating new tag
      * usage in : /posts/add.ctp
      */
    function addTag(){
        $this->layout = 'ajax';
        Configure::write('debug',0);
        App::import('Sanitize');

        /* Defining tags array variables from ajax input */
        $tags = $this->_filterTag($this->params['form']['tags']);
        $post_id = Sanitize::paranoid($this->params['form']['id']);

        if(empty($tags)){$this->Json->error('0');}
        if(empty($post_id)){$this->Json->error('1');}

        /* Saving tags */
        $this->Post->Tag->saveTags($tags);

        /* Get tags id */
        $tagList = $this->Post->Tag->getTagsId($tags);

        /* Update counter as CounterCache on HABTM relation */
        $this->Post->Tag->updateCounter($tagList);

        /* Creating data on Join Table HABTM */
        $this->data['Tag']['Tag'] = $tagList;

        /* For updating data using save, we must give post_id value */
        $this->Post->id = $post_id;

        if($this->Post->save($this->data)){
            $this->Json->show(array('result'=>'1','tags'=>implode(" ",$tags)));     // Show result and tags
        }
    }
    
  /**
    * First function of search page
    * accessed from view : Photos -> view.ctp, home.ctp, index.ctp and Post-> search.ctp
    */
    function find(){
        $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
        if(!empty($referer)){
            $this->_getReferalHost($referer);
        }

        $randomPosts = $this->Post->getRandomPost();
        $this->set(compact('randomPosts'));
        $query = $this->data['Post']['find'];
        if(!empty($query)){
            $input = $this->_filterQuery($query);
            $this->redirect('/search/'.$input);
        }
    }

   /**
    * SEARCH ENGINE
    * view /search
    */
    function search($query = null){
        $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
        if(!empty($referer)){
            $this->_getReferalHost($referer);
        }

        $input = $this->_filterQuery($query);
        $this->pageTitle = strtoupper(str_replace('+',' ',$input)).' - Freelogo.web.id';
        
        $this->set('randomPosts',$this->Post->getRandomPost());
        

        if(!empty($input)){
            $this->Post->bindModel(
                array('hasOne' => array('Catalog')
                )
            );
            
            /* Matching input with category */
            $getPostByCategory = $this->Post->Catalog->find('list',array('conditions'=>array("MATCH(Catalog.category) AGAINST('$input' IN BOOLEAN MODE)"),'fields'=>'Catalog.post_id'));
            
            if(empty($getPostByCategory)){
                
                /* Matching input with title */
                $getPostByTitle = $this->Post->Catalog->find('list',array('conditions'=>array("MATCH(Catalog.title) AGAINST('$input' IN BOOLEAN MODE)"),'fields'=>'Catalog.post_id'));
                
                /* Matching input with description */
                $getPostByTag = $this->Post->Catalog->find('list',array('conditions'=>array("MATCH(Catalog.tag) AGAINST('$input' IN BOOLEAN MODE)"),'fields'=>'Catalog.post_id'));
                
               /* Matching input with description */
                $getPostByDescription = $this->Post->Catalog->find('list',array('conditions'=>array("MATCH(Catalog.description) AGAINST('$input' IN BOOLEAN MODE)"),'fields'=>'Catalog.post_id'));

                $getPostByDesc = array_unique(am($getPostByTitle,$getPostByDescription,$getPostByTag));

                if(!empty($getPostByDesc)){
                    $this->paginate = $this->Post->paginateSearch($getPostByDesc);
                     $postNews = $this->_filterDescription($this->paginate('Post',array('AND'=>array('Post.post_id'=>$getPostByDesc,'Post.status'=>'1'))));
                    $this->set('postResults',$postNews);
                } else {
                    $this->set('warning',$input);
                }
            }else{
                 $PostId = $getPostByCategory;

                 /* Get post_id by matching between title and input */
                $getTitle = $this->Post->Catalog->find('list',array('conditions'=>array('AND'=>array("MATCH(Catalog.title) AGAINST('$input' IN BOOLEAN MODE)",'Catalog.status'=>'1')),'fields'=>'Catalog.post_id'));
                $titleList = array();
                
                if(!empty($PostId)){
                    $this->paginate = $this->Post->paginateSearch($PostId);
                     $postNews = $this->_filterDescription($this->paginate('Post',array('AND'=>array('Post.post_id'=>$PostId,'Post.status'=>'1'))));
                    $this->set('postResults',$postNews);
                } else {
                    $warning = str_replace("+"," ",$input);
                    $this->set('warning',$warning);
                }
            }
        }else{
            $this->redirect('/finds');
        }
    }

    /**
     * Uploading posts from users
     * usage in : /posts/upload.ctp
     */
    function upload() {
        $this->layout = 'ajax';
        Configure::write('debug',0);
        if (!empty($this->data) &&  is_uploaded_file($this->data['Post']['filedata']['tmp_name'])) {
            $file             = $this->data['Post']['filedata'];                                                    // data from upload file

            $dir             		= $this->_initializeDirectory();													// Initialize two variables, directory and thumbnail directory
            $folderDir			= $dir['0'];
            $folderThumb	= $dir['1'];

            $directory 		= $this->_setDirectory($folderDir);													 // address of logo images
            $thumbDir 		= $this->_setDirectory($folderThumb);											//address of logo thumbnails

            $result					= $this->Upload->upload($directory,$thumbDir,$file);               // uploading logo

            $errors = $this->Upload->errors;																			// read error from Upload component
            if($errors){
                if(is_array($errors)){
                    $errors = implode("<br />",$errors);
                }
                $this->Json->error($errors);
            } else {																													// ready to saving data
                $this->Post->create();
                $logos = $this->Upload->logos;
                $logoFolder = $this->Post->Path->checkFolder($logos['Post']['url']);
                if(is_array($logoFolder)){
                    $logos['Post']['path_id'] = $logoFolder['Path']['path_id'];
                } else {
                    $this->data['Path']['name'] = $logos['Post']['url'];
                }
                
                $this->data = array_merge($this->data,$logos);																// merge logos array to $this->data
                if ($this->Post->saveAll($this->data)) {

                    /* Saving Folder Id to Post tables */
                    $logos['Post']['path_id']	= $this->Post->Path->id;

                     /* LInking Post and Catalog*/
                    $this->Post->bindModel(
                        array('hasOne' => array('Catalog'=>array('className'=>'Catalog','foreignKey'=>'post_id'))
                        )
                    );
                    $catalogId= $this->Post->Catalog->createData($this->Post->id);

                    $catalogId = $catalogId;
                    $logoLastId = $this->Post->id;
                    $result = array('result'=>'1','thumb'=>$this->Upload->result['4'],'created'=>$logos['Post']['created'],'logo'=>$logoLastId,'catalog'=>$catalogId);
                    $this->Json->show($result);
                } else {
                    unlink($this->Upload->result['0']);
                    unlink($this->Upload->result['1']);
                    unlink($this->Upload->result['2']);
                    unlink($this->Upload->result['3']);
                    $this->Json->error('11');
                }
            }
        } else {
            $this->Json->error('4');
        }
    }

/**
 * ========================== ALL PRIVATE FUNCTION PLACED HERE ======================
 *
 */

   /**
     * Get host referer
     * usage in : view, about, index, terms, privacy, search, contact, copyright, help
     */
    function _getReferalHost($referer) {
        $url = parse_url($referer);
        $host = $url['host'];
        $refer = isset($url['query']) ? $url['query'] : '';
        if(empty($refer)){
            $refer = isset($url['fragment']) ? $url['fragment'] : '';
        }

        if(!empty($refer)){
            $this->Term = ClassRegistry::init('Term');

            if(strstr($host,'google')){
                //do google stuff
                $match = preg_match('/&q=([a-zA-Z0-9+-]+)/',$refer, $output);
                if(empty($ouput)){
                    $match = preg_match('/q=([a-zA-Z0-9+-]+)/',$refer, $output);
                    $querystring = $output[0];
                    $querystring = str_replace('q=','',$querystring);
                    $keywords = str_replace('+',' ',$querystring);
                }else{
                    $querystring = $output[0];
                    $querystring = str_replace('&q=','',$querystring);
                    $keywords = str_replace('+',' ',$querystring);
                }

                $this->Term->saveTerms($keywords,$host);

                return array('<a href="'.$referer.'">google.com</a>',$keywords);
            }
            elseif(strstr($host,'yahoo')){
                 //do yahoo stuff
                $match = preg_match('/p=([a-zA-Z0-9+-]+)/',$refer, $output);
                $querystring = $output[0];
                $querystring = str_replace('p=','',$querystring);
                $keywords = str_replace('+',' ',$querystring);

                $this->Term->saveTerms($keywords,$host);

                return array('<a href="'.$referer.'">search.yahoo.com</a>',$keywords);

            }
            elseif(strstr($host,'bing')){
                //do msn stuff
                $match = preg_match('/q=([a-zA-Z0-9+-]+)/',$refer, $output);
                $querystring = $output[0];
                $querystring = str_replace('q=','',$querystring);
                $keywords = str_replace('+',' ',$querystring);

                $this->Term->saveTerms($keywords,$host);

                return array('<a href="'.$referer.'">bing.com</a>',$keywords);

            } else{
                //do msn stuff
                $match = preg_match('/q=([a-zA-Z0-9+-]+)/',$refer, $output);
                if(!empty($match)){
                    $querystring = $output[0];
                    $querystring = str_replace('q=','',$querystring);
                    $keywords = str_replace('+',' ',$querystring);
                }else{
                    $host = $referer;
                    $keywords = 'unknown';
                }

                $this->Term->saveTerms($keywords,$host);

                return 'Search Engine';
            }
        }else{
            $this->Referal = ClassRegistry::init('Referal');
            $this->Referal->updateReferal($host);
        }
    }

    /**
     * Modifying and cropping Post description to be one paragraph only
     * usage in : function home()
     */
    function _filterDescription($input){
        $list = array();
        foreach($input as $value => &$key){
            $paragraphs = explode('</p>',$key['Post']['description']);
            $firstParagraph = $paragraphs[0].'</p>';
            $key['Post']['description']= $firstParagraph;
            $list[$value] = $key;
        }

        return $list;
    }

    /**
     * Modifying and cropping comment description to be one paragraph only
     * usage in : function home()
     */
    function _filterComment($input){
        $list = array();
        foreach($input as $value => &$key){
            $paragraphs = explode('</p>',$key['Comment']['description']);
            $firstParagraph = $paragraphs[0];
            $pos = strpos($firstParagraph, '.',3);
            $tempWords = substr($firstParagraph,0,$pos);
            $getWords = str_replace('<p>','',$tempWords);
            $getDefault = str_replace('<p>','',$firstParagraph);
            if(empty($tempWords)){
                $key['Comment']['description']= $getDefault;
            }else{
                $key['Comment']['description']= $getWords;
            }
            $list[$value] = $key;
        }

        return $list;
    }

    /**
     * Filtering query input to be like this : a b c = a+b+c
     * usage in function search() and find()
     */
    function _filterQuery($query){
        $list = array();
        App::import('Sanitize');
        $filterQuery = explode(" ",strtolower($query));               // lowercase input
        foreach ($filterQuery as $value =>&$key){
            $clearValue = Sanitize::paranoid($key);
            if(!empty($clearValue)){
                $list[$value] = $clearValue;
            }
        }
        $input = implode("+", $list);

        return $input;
    }


    /**
     * Filtering Tag
     * usage in function addTag()
     */
    function _filterTag($input){
        $lower = strtolower($input);
        $newInput = str_replace(", ",",",$lower);
        $getInputs = array_unique(explode(",",$newInput));
        $list = array();
        foreach($getInputs as $value => &$key){
            $value = Sanitize::escape($key);
            if(!empty($value)){
                $list[$value] = $value;
            }
        }
        return $list;
    }

    /**
     * Secure directory by copy index.php and .htaccess on each directory
     */
    function _lockDirectory($uploadDir) {
        $_index = ROOT.DS.APP_DIR.DS.'webroot'.DS.'img'.DS.'index.php ';																										// index.php
        $_htaccess= ROOT.DS.APP_DIR.DS.'webroot'.DS.'.htaccess ';																															// .htaccess

        exec('cp '.$_index.' '.$uploadDir);
    }

    /**
     * Initialize folder address for logos image place
     */
    function _initializeDirectory(){
        $_directory = ROOT.DS.APP_DIR.DS.'webroot'.DS.'img'.DS.'logos'.DS; 	// directory logo image
        $_thumb = ROOT.DS.APP_DIR.DS.'webroot'.DS.'img'.DS.'thumbs'.DS; 	// directory logo thumbnail

        return array($_directory,$_thumb);
    }

    /**
     * Create upload directory by date 
     */
    function _setDirectory($directory){
        if(!file_exists($directory)) {
            new Folder($directory, true);
            $this->_lockDirectory($directory);
        }

        $day = date('d');
        $month = date('m');
        $year = date('Y');

        $uploadDir = $directory.$year.'/';
        if(!file_exists($uploadDir)) {
            new Folder($uploadDir, true);
            $this->_lockDirectory($uploadDir);
        }

        $uploadDir = $uploadDir.$month.'/';
        if(!file_exists($uploadDir)) {
            new Folder($uploadDir, true);
            $this->_lockDirectory($uploadDir);
        }

        $uploadDir = $uploadDir.$day.'/';
        if(!file_exists($uploadDir)) {
            new Folder($uploadDir, true);
            $this->_lockDirectory($uploadDir);
        }

        return $uploadDir;
    }

    /**
     * Initialize folder address for logos image place
     */
    function _initializeFileDirectory($input){
        $_directory = ROOT.DS.APP_DIR.DS.'webroot'.DS.'files'.DS.$input.DS; 	// file directory

        return $_directory;
    }

    /**
     * Create upload directory by date
     */
    function _setFileDirectory($directory){
        if(!file_exists($directory)) {
            new Folder($directory, true);
            $this->_lockDirectory($directory);
        }

        $month = date('m');
        $year = date('Y');

        $uploadDir = $directory.$year.'/';
        if(!file_exists($uploadDir)) {
            new Folder($uploadDir, true);
            $this->_lockDirectory($uploadDir);
        }

        $uploadDir = $uploadDir.$month.'/';
        if(!file_exists($uploadDir)) {
            new Folder($uploadDir, true);
            $this->_lockDirectory($uploadDir);
        }

        return $uploadDir;
    }
}
?>